package main

import (
	"context"
	"gitee.com/ziEgate/mq/rabbitmq"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"sync"
	"time"
)

var message = []byte(
	`			<Message>
			<Header>
			<MESSAGENAME>AreYouThereRequest</MESSAGENAME>
			<SHOPNAME>Z10000</SHOPNAME>
			<MACHINENAME>Z1COCK01</MACHINENAME>
			<TRANSACTIONID>20240726151621152951</TRANSACTIONID>
			<ORIGINALSOURCESUBJECTNAME>PKAOWRQPJH-Z1TYYT01-AreYouThereRequest</ORIGINALSOURCESUBJECTNAME>
			<SOURCESUBJECTNAME>ZL.FMM.MES.TEST.8MMPI91</SOURCESUBJECTNAME>
			<TARGETSUBJECTNAME>ZL.FMM.MES.TEST.PEXsvr</TARGETSUBJECTNAME>
			<EVENTUSER>Z1TYYT01</EVENTUSER>
			<EVENTCOMMENT>AreYouThereRequest</EVENTCOMMENT>
			</Header>
			<Body>
			<MACHINENAME>Z1TYYT01</MACHINENAME>
			</Body>
			<Return>
			<RETURNCODE></RETURNCODE>
			<RETURNMESSAGE></RETURNMESSAGE>
			</Return>
			</Message>
`)

func main() {
	errorChan := make(chan error, 128)
	go func() {
		_ = http.ListenAndServe("localhost:6060", nil)
	}()

	dialOpt := &rabbitmq.DialOption{
		Username: "manager",
		Password: "admin123",
		Host:     "10.1.36.190",
		Port:     "5671",
		VHost:    "/mes",
	}

	eqToSysExc := &rabbitmq.ExchangeOption{
		Name:       "MES.PRD.EAP.SVR",
		Kind:       "topic",
		AutoDelete: false,
		Durable:    true,
		NoWait:     false,
		Args:       nil,
	}

	sysToEQExc := &rabbitmq.ExchangeOption{
		Name:       "MES.PRD.EAP.SVR",
		Kind:       "topic",
		AutoDelete: false,
		Durable:    true,
		NoWait:     false,
		Args:       nil,
	}

	sysReplyToEQQue := &rabbitmq.QueueOption{
		Name:       "MES.DEV.EDGE.G21",
		AutoDelete: false,
		Durable:    true,
		Exclusive:  false,
		NoWait:     false,
		Args:       nil,
	}

	// sysToEQQue := &rabbitmq.QueueOption{
	// Name:       "SDK.SIHONG.SPC.PRD.FAB.SPCtoEQ.QUE",
	// AutoDelete: true,
	// Durable:    true,
	// Exclusive:  false,
	// NoWait:     false,
	// Args:       nil,
	// }

	eqToSysKey := "MES.PRD.EAP.PEXsvr"

	sysReplyToEQKey := "MES.DEV.EDGE.G21"

	// sysToEQKey := "SDK.SIHONG.SPC.PRD.FAB.SPCtoEQ.KEY"
	var mesObject sync.Map

	f := func(machineName string) {
		producer, err := rabbitmq.NewTopicProducer(
			machineName,
			dialOpt,
			eqToSysExc,
			sysToEQExc,
			sysReplyToEQQue,
			sysReplyToEQKey,
			"Egate",
			errorChan,
		)
		if err != nil {
			log.Fatal(err)
		}

		mesObject.Store(machineName, producer)

		defer func() {
			mq, exists := mesObject.LoadAndDelete(machineName)
			if exists {
				err = mq.(*rabbitmq.TopicProducer).Close()
				if err != nil {
					log.Println(machineName, err)
				} else {
					log.Println("close", machineName)
				}
			}
		}()

		for {
			_, err = producer.SendRequest(context.Background(), eqToSysKey, false, false, message, 10*time.Second)
			if err != nil {
				log.Println(err)
				return
			}

			time.Sleep(time.Second)

		}
	}

	go f("1")
	// go f("2")
	// go f("3")
	for {
		select {}
	}
	// consumer, err := rabbitmq.NewTopicConsumer(
	//	dialOpt,
	//	sysToEQExc, eqToSysExc,
	//	&rabbitmq.ConsumerOption{
	//		Name:      "EQ",
	//		AutoAck:   false,
	//		Exclusive: false,
	//		NoWait:    false,
	//		Args:      nil,
	//	},
	//	errorChan,
	// )
	// if err != nil {
	//	log.Fatal(err)
	// }
	//
	// msgs, err := consumer.Recv(
	//	sysToEQQue,
	//	sysToEQKey,
	// )
	// if err != nil {
	//	log.Fatal(err)
	// }

	var (
		wg sync.WaitGroup
		t  time.Time
	)

	wg.Add(1)
	go func() {
		defer wg.Done()

		count := 30 * 20
		t = time.Now()

		wg.Add(count)
		for range count {
			go func() {
				defer wg.Done()

				// _, err := producer.SendRequest(context.Background(), eqToSysKey, false, false, message, 10*time.Second)
				// if err != nil {
				//	errorChan <- err
				//
				//	return
				// }
			}()
		}
	}()

	wg.Wait()
	log.Println(time.Since(t))

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	for {
		select {
		case <-ctx.Done():
			os.Exit(0)
		case e := <-errorChan:
			log.Println(e)
		}
	}
}
